#include "functions.h"

void mkdir_for_gnuplot(){
  char ans[2];

  if ( mkdir( "./gnuplot",
             S_IRUSR | S_IWUSR | S_IXUSR |         
             S_IRGRP | S_IWGRP | S_IXGRP |         
             S_IROTH | S_IXOTH | S_IXOTH) == 0)
    { 
      /***** empty *****/
    } else {
    printf( "[Error] Cannot create \"./%s\" Directory!!\n", dirname );

    while( 1 )
      {
	printf( "If you delete %s ? (y/n)\n", dirname );
	fgets( ans, sizeof(ans), stdin );

	if( strcmp( "N", ans ) == 0 || strcmp( "n", ans ) == 0 )
	  {
	    printf( "Exit!!\n" );
	    exit( 0 );
	  }
	else if( strcmp( "Y", ans ) == 0 || strcmp( "y", ans ) == 0)
	  {
	    rmdir_all( "./gnuplot" );
	    mkdir( "./gnuplot", S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | 
		   S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH | S_IXOTH);
	    break;
	  }
      } // end while

  }

  mkdir( "./gnuplot/data", S_IRUSR | S_IWUSR | S_IXUSR |
             S_IRGRP | S_IWGRP | S_IXGRP |
	     S_IROTH | S_IXOTH | S_IXOTH );
}

// Reference -> http://www.upotu.com/wordpress/?p=76
int rmdir_all( const char* dirname ){
  int ret = 0;
  char tmp[256] ="";
  struct stat* fileinfo = malloc( sizeof( struct stat ) );

  stat( dirname, fileinfo );

  if( S_ISDIR( fileinfo->st_mode ) ){

    //ディレクトリの場合
    DIR* dir = opendir( dirname );
    struct dirent* dp;
    while( ( dp = readdir( dir ) ) != NULL){
      if( strcmp( dp->d_name, "." ) == 0 || strcmp( dp->d_name, ".." ) == 0){
      }
      else{
	strcpy( tmp, dirname );
	strcat( tmp, "/" );
	strcat( tmp, dp->d_name );
	ret = rmdir_all( tmp );
      }
    }
    //ディレクトリを削除;
    rmdir( dirname );
  }else{
    //ファイルの場合はremoveで削除
    remove( dirname );
  }
  free( fileinfo );
  return 0;
}

void finalize_for_gnuplot(){
  int i;
  char filename[ 30 ];
  FILE *fp;

  // Write file for plot
  strcpy( filename, "./gnuplot/plot.dem" );
  fp = fopen( filename, "w" );
  
  fprintf( fp, "call \"P1\" \"$0\" \"$1\"\n" );
  fprintf( fp, "pause -1\n" );
  fprintf( fp, "pause 1\n" );

  for( i=1; i<number_of_generations; i++ )
    {
      fprintf( fp, "call \"P%d\" \"$0\" \"$1\"\n", i);
      fprintf( fp, "pause 0.1\n" );
    }

  fclose( fp );
  
  // Write file for plot
  strcpy( filename, "./gnuplot/neighbor.dem" );
  fp = fopen( filename, "w" );

  fprintf( fp, "call \"C1\" \"$0\" \"$1\"\n" );
  fprintf( fp, "pause -1\n" );
  fprintf( fp, "pause 1\n" );

  for( i=1; i<number_of_generations; i++ )
    {
      fprintf( fp, "call \"C%d\" \"$0\" \"$1\"\n", i);
      fprintf( fp, "pause 0.1\n" );
    }

  fclose( fp );

}

void write_plot_for_gnuplot(){
  int i;
  char filename[30];
  FILE *fp;

  // Discription of Plot File -> ./gnuplot/data/[number_of_generations]
  sprintf( filename, "./gnuplot/data/%d", number_of_generations );

  fp = fopen(filename, "w" );

  for(i=0;i<total_population_size;i++)
    fprintf( fp, "%f\t%f\t%f\n", individuals[i].design_variables[0], individuals[i].design_variables[1], individuals[i].function_value);

  fclose( fp );

  
  // Discription of Gnuplot file -> ./gnuplot/P[number_of_generations]
  sprintf( filename, "./gnuplot/P%d", number_of_generations );

  fp = fopen(filename, "w" );
  
  fprintf( fp, "set xrange [$0:$1]\n");
  fprintf( fp, "set yrange [$0:$1]\n");
  fprintf( fp, "set palette defined (0 \"white\", 80 \"blue\")\n");
  fprintf( fp, "set title \"%s Gen = %d\"\n", function_name, number_of_generations );
  fprintf( fp, "set isosample 120\n");
  fprintf( fp, "set ticslevel 0\n");
  fprintf( fp, "set size square\n");
  fprintf( fp, "set view 0,0\n");
  
  if( strcmp( function_name, "Rastrigin-1.0" ) == 0 ){

    fprintf( fp, "splot 10 * 2 + ((x-1)*(x-1) - 10 * cos(2*pi*(x-1))) + ((y-1)*(y-1) - 10 * cos(2*pi*(y-1))) with pm3d ti \"\", \\\n");

  } else if( strcmp( function_name, "Rosenbrock-Star" ) == 0 || strcmp( function_name, "Rosenbrock-Chain" ) == 0 ){
        
    fprintf( fp, "splot 100*(x-y*y)*(x-y*y) + (1-y)*(1-y) with pm3d ti \"\", \\\n");

  } else if( strcmp( function_name, "Schwefel" ) == 0 ){
        
    fprintf( fp, "splot x*sin(sqrt(abs(x))) + y*sin(sqrt(abs(y))) + 418.98288727*2 with pm3d ti \"\", \\\n");
                
  } else if( strcmp( function_name, "Ridge" ) == 0 ){
        
    fprintf( fp, "splot x*x + (x + y) * (x + y) with pm3d ti \"\", \\\n");
                
  } else if( strcmp( function_name, "Griewank" ) == 0 ){

    fprintf( fp, "splot 1 + (x*x + y*y)/4000 - cos(x) * cos((y)/sqrt(2)) with pm3d ti \"\", \\\n");

  } else if( strcmp( function_name, "Sphere" ) == 0 ){
        
    fprintf( fp, "splot x*x + y*y with pm3d ti \"\", \\\n");
        
  } else if( strcmp( function_name, "Ellipsoid" ) == 0 ){

    fprintf( fp, "splot x*x + 1000*1000*y*y with pm3d ti \"\", \\\n");
          
  } else if( strcmp( function_name, "k-tablet" ) == 0 ){

    fprintf( fp, "splot x*x + 100*100*y*y with pm3d ti \"\", \\\n");

  } else if( strcmp( function_name, "Bohachevsky" ) == 0 ){

    fprintf( fp, "splot x*x + 2*y*y - 0.3 * cos(3*pi*x) - 0.4 * cos(4*pi*y) + 0.7 with pm3d ti \"\", \\\n");
        
  } else if( strcmp( function_name, "Ackley" ) == 0 ){

    fprintf( fp, "splot 20+exp(1)-20*exp(-0.2*sqrt(0.5*(x*x+y*y)))-exp(0.5*(cos(2*pi*x)+cos(2*pi*y))) with pm3d ti \"\", \\\n");

  } else if( strcmp( function_name, "Schaffer" ) == 0 ){

    fprintf( fp, "splot (x*x+y*y)**0.25 * (sin(50*(x*x+y*y)**0.1)**2 + 1.0) with pm3d ti \"\", \\\n");
  }
  
  fprintf( fp, "\"data/%d\" with points pt 5 lt 3, \\\n", number_of_generations );

  // Write Optimum point
  if( strcmp( function_name, "Rastrigin-1.0" ) == 0 || strcmp( function_name, "Rosenbrock-Star" ) == 0 || strcmp( function_name, "Rosenbrock-Chain" ) == 0 ){

    fprintf(fp, "\"optimam1.dat\" with points pointsize 2 pt 9 lt 1");

  } else if( strcmp( function_name, "Schwefel" ) == 0 ){
    
    fprintf(fp, "\"optimam420.dat\" with points pointsize 2 pt 9 lt 1");

  } else if( strcmp( function_name, "Ridge" ) == 0 || strcmp( function_name, "Griewank" ) == 0 ){

    fprintf(fp, "\"optimam0.dat\" with points pointsize 2 pt 9 lt 1");

  } else if( strcmp( function_name, "Sphere" ) == 0 || strcmp( function_name, "Ellipsoid" ) == 0 ){

    fprintf(fp, "\"optimam0.dat\" with points pointsize 2 pt 9 lt 1");

  } else if( strcmp( function_name, "k-tablet" ) == 0 || strcmp( function_name, "Bohachevsky" ) == 0 ){

    fprintf(fp, "\"optimam0.dat\" with points pointsize 2 pt 9 lt 1");

  } else if( strcmp( function_name, "Ackley" ) == 0 || strcmp( function_name, "Schaffer" ) == 0 ){

    fprintf(fp, "\"optimam0.dat\" with points pointsize 2 pt 9 lt 1");

  }

  fclose( fp );

  // Create Optimum point file
  strcpy( filename, "./gnuplot/optimam1.dat" );
  fp = fopen( filename, "w" );
  fprintf( fp, "1\t1\t0\n" );
  fclose( fp );

  strcpy( filename, "./gnuplot/optimam0.dat" );
  fp = fopen( filename, "w" );
  fprintf( fp, "0\t0\t0\n" );
  fclose( fp );

  strcpy( filename, "./gnuplot/optimam420.dat" );
  fp = fopen( filename, "w" );
  fprintf( fp, "-420.96875\t-420.96875\t0\n" );
  fclose( fp );

}

void write_neighborhood_for_gnuplot(){
  int i;
  char filename[30];
  FILE *fp;

  sprintf( filename, "./gnuplot/C%d", number_of_generations );
  fp = fopen(filename, "w" );
  
  fprintf( fp, "set xrange [$0:$1]\n");
  fprintf( fp, "set yrange [$0:$1]\n");
  fprintf( fp, "set title \"%s Gen = %d\"\n", function_name, number_of_generations );
  fprintf( fp, "set parametric\n" );
  fprintf( fp, "set size square\n" );
  
  if( strcmp( function_name, "Rastrigin-1.0" ) == 0 || strcmp( function_name, "Rosenbrock-Star" ) == 0 || strcmp( function_name, "Rosenbrock-Chain" ) == 0 ){

    fprintf( fp, "plot 1, 1 with points pointsize 2 pointtype 9 ti \"\" ,\\\n");

  } else if( strcmp( function_name, "Schwefel" ) == 0 ){
    
    fprintf( fp, "plot -420.96875, -420.96875 with points pointsize 2 pointtype 9 ti \"\" ,\\\n");

  } else if( strcmp( function_name, "Ridge" ) == 0 || strcmp( function_name, "Griewank" ) == 0 ){

    fprintf( fp, "plot 0, 0 with points pointsize 2 pointtype 9 ti \"\" ,\\\n");

  } else if( strcmp( function_name, "Sphere" ) == 0 || strcmp( function_name, "Ellipsoid" ) == 0 ){

    fprintf( fp, "plot 0, 0 with points pointsize 2 pointtype 9 ti \"\" ,\\\n");

  } else if( strcmp( function_name, "k-tablet" ) == 0 || strcmp( function_name, "Bohachevsky" ) == 0 ){

    fprintf( fp, "plot 0, 0 with points pointsize 2 pointtype 9 ti \"\" ,\\\n");

  } else if( strcmp( function_name, "Ackley" ) == 0 || strcmp( function_name, "Schaffer" ) == 0 ){

    fprintf( fp, "plot 0, 0 with points pointsize 2 pointtype 9 ti \"\" ,\\\n");

  }

  for( i=0; i<number_of_layers-1; i++){
    fprintf( fp, "%f*sin(t) + %f, %f*cos(t) + %f ti \"L=%d\" ,\\\n",
	     layers[ i ].sigma[ 0 ], layers[ i ].center[ 0 ], layers[ i ].sigma[ 1 ], layers[ i ].center[ 1 ], i);
  }
  
  i = number_of_layers - 1;
  fprintf( fp, "%f*sin(t) + %f, %f*cos(t) + %f ti \"L=%d\"",
	   layers[ i ].sigma[ 0 ], layers[ i ].center[ 0 ], layers[ i ].sigma[ 1 ], layers[ i ].center[ 1 ], i);

  fclose( fp );

}
